home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / abuse / src / net / unix / netfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-30  |  11.9 KB  |  461 lines

  1. #include "indian.hpp"
  2. #include "netfile.hpp"
  3. #include "../inc/netface.hpp"
  4. #include "engine.hpp"
  5.  
  6.  
  7. nfs_client *first_nfs_client=NULL;
  8. remote_file *remote_file_list=NULL;
  9. char default_fs_name[256];    // default file server name (set with parm -fs)
  10.  
  11. nfs_client::nfs_client(net_socket *sock, int file_fd, nfs_client *next) : 
  12.   sock(sock),file_fd(file_fd),next(next),size_to_read(0)
  13.   sock->read_selectable();
  14. }  
  15.  
  16.  
  17. nfs_client::~nfs_client() 
  18.   delete sock;
  19.   if (file_fd>=0)
  20.     close(file_fd);
  21. }
  22.  
  23. void secure_filename(char *filename, char *mode)
  24. {
  25.   if (!no_security)
  26.   {    
  27.     if (filename[0]=='/') { filename[0]=0; return ; }
  28.     int level=0;
  29.     char *f=filename;
  30.     while (*f)
  31.     {
  32.       if (*f=='/') { f++; level++; }
  33.       else if (*f=='.' && f[1]=='.')
  34.       {
  35.     if (f[3]=='.') while (*f!='.') f++;
  36.     else
  37.     {
  38.       f+=2;
  39.       level--;
  40.     }
  41.       } else f++; 
  42.       
  43.     }
  44.     if (level<0)
  45.       filename[0]=0;
  46.   }
  47. }
  48.  
  49.  
  50. int local_address(char *server_name)    // returns 1 if server name is ourself
  51. {
  52.   struct hostent *hn=gethostbyname(server_name);    // first check to see if this address is 127.0.0.1
  53.   if (!hn) return 0;                                // if bad server_name, return false
  54.   char **ip_address=hn->h_addr_list;
  55.   while (*ip_address) 
  56.   {
  57.     char *a=*ip_address;
  58.     if (a[0]==127 && a[1]==0 && a[2]==0 && a[3]==1)
  59.       return 1;
  60.     ip_address++;
  61.   }
  62.   char server_ip[4];
  63.   memcpy(server_ip,hn->h_addr_list,4);
  64.  
  65.   char my_name[100];                              // now check to see if this address is 'hostname'
  66.   gethostname(my_name,100);
  67.   struct hostent *l_hn=gethostbyname(my_name);  
  68.   char **l_ip_address=l_hn->h_addr_list;
  69.  
  70.   while (*l_ip_address)  // local ip_address
  71.   {
  72.     char *a=*l_ip_address;         // scan through all local ip's
  73.     ip_address=hn->h_addr_list;
  74.     while (*ip_address)            // scan through all ip's for server_name
  75.     {
  76.       char *b=server_ip;
  77.       if (a[0]==b[0] && a[1]==b[1] && a[2]==b[2] && a[3]==b[3])    // check for match
  78.         return 1;
  79.       ip_address++;
  80.     }
  81.     l_ip_address++;
  82.   }
  83.   return 0;       // didn't match localhost nor hostname, must be somewhere else
  84. }
  85.  
  86. int nfs_client::send_read()   // return 0 if failure on socket, not failure to read
  87. {
  88.   if (file_fd>=0 && socket_fd>=0)
  89.   {
  90.     // first make sure the socket isn't 'full'
  91.  
  92.     struct timeval tv={0,0};     // don't wait
  93.     fd_set write_check;  
  94.     FD_ZERO(&write_check);  
  95.     FD_SET(socket_fd,&write_check);     
  96.     select(FD_SETSIZE,NULL,&write_check,NULL,&tv);
  97.  
  98.     if (FD_ISSET(socket_fd,&write_check))            // ready to write?
  99.     {
  100.       char buf[READ_PACKET_SIZE];   
  101.       short read_total;
  102.       short actual;
  103.  
  104.       do
  105.       {      
  106.     read_total=size_to_read>(READ_PACKET_SIZE-2) ? (READ_PACKET_SIZE-2) : size_to_read;
  107.     actual=read(file_fd,buf,read_total);
  108.     actual=lstl(actual);
  109.     if (write(socket_fd,&actual,sizeof(actual))!=sizeof(actual))
  110.     {
  111.       fprintf(stderr,"write failed\n");
  112.       return 0;
  113.     }
  114.     actual=lstl(actual);
  115.  
  116.     int write_amount=write(socket_fd,buf,actual);
  117.     if (write_amount!=actual) 
  118.     {
  119.       fprintf(stderr,"write failed\n");
  120.       return 0;
  121.     }
  122.  
  123.     size_to_read-=actual;
  124.  
  125.     FD_ZERO(&write_check);  
  126.     FD_SET(socket_fd,&write_check);     
  127.     select(FD_SETSIZE,NULL,&write_check,NULL,&tv);
  128.  
  129.     if (!FD_ISSET(socket_fd,&write_check))
  130.     {
  131.       FD_SET(socket_fd,&master_write_set);      // socket is full, wait for it empty
  132.       FD_CLR(socket_fd,&master_set);            // don't check for reading or process commands till read is done
  133.       return 1;    // not ok to write anymore, try again latter
  134.     }
  135.  
  136.       } while (size_to_read && actual==read_total);
  137.       size_to_read=0;
  138.       FD_CLR(socket_fd,&master_write_set);       // don't check this socket for write ok
  139.       FD_SET(socket_fd,&master_set);             // check it for reading
  140.       return 1;
  141.     } else 
  142.     {
  143.       FD_SET(socket_fd,&master_write_set);      // socket is full, wait for it empty
  144.       FD_CLR(socket_fd,&master_set);            // don't check for reading or process commands till read is done
  145.       return 1;
  146.     }
  147.   }
  148.   return 0;
  149. }
  150.  
  151.  
  152. int process_nfs_command(nfs_client *c)
  153. {
  154.   char cmd;
  155.   if (read(c->socket_fd,&cmd,1)!=1) return 0;
  156.   switch (cmd)
  157.   {
  158.     case NFCMD_READ :
  159.     {
  160.       long size;
  161.       if (read(c->socket_fd,&size,sizeof(size))!=sizeof(size)) return 0;
  162.       size=lltl(size);
  163.  
  164.       c->size_to_read=size;
  165.       return c->send_read();
  166.     } break;
  167.     case NFCMD_CLOSE :
  168.     {
  169.       return 0;
  170.     } break;
  171.     case NFCMD_SEEK :
  172.     {
  173.       long offset;
  174.       if (read(c->socket_fd,&offset,sizeof(offset))!=sizeof(offset)) return 0;
  175.       offset=lltl(offset);
  176.       offset=lseek(c->file_fd,offset,0);
  177.       offset=lltl(offset);
  178.       if (write(c->socket_fd,&offset,sizeof(offset))!=sizeof(offset)) return 0;
  179.       return 1;
  180.     } break;
  181.     case NFCMD_TELL :
  182.     {
  183.       long offset=lseek(c->file_fd,0,SEEK_CUR);
  184.       offset=lltl(offset);
  185.       if (write(c->socket_fd,&offset,sizeof(offset))!=sizeof(offset)) return 0;
  186.       return 1;
  187.     } break;
  188.     
  189.     default :
  190.     { fprintf(stderr,"net driver : bad command from nfs client\n");
  191.       return 0;
  192.     }
  193.   } 
  194. }
  195.  
  196.  
  197.  
  198. void add_nfs_client(int fd)
  199. {
  200.   uchar size[2];
  201.   char filename[300],mode[20],*mp;
  202.   if (read(fd,size,2)!=2) { close(fd); return ; }
  203.   if (read(fd,filename,size[0])!=size[0]) { close(fd); return ; }
  204.   if (read(fd,mode,size[1])!=size[1]) { close(fd); return ; }
  205.  
  206.   fprintf(stderr,"remote request for %s ",filename);
  207.  
  208.   secure_filename(filename,mode);  // make sure this filename isn't a security risk
  209.   if (filename[0]==0) { fprintf(stderr,"(denied)\n"); close(fd); return ; }
  210.  
  211.   mp=mode;
  212.   int flags=0;
  213.  
  214.   while (*mp)
  215.   {
  216.     if (*mp=='w') flags|=O_CREAT|O_RDWR;
  217.     else if (*mp=='r') flags|=O_RDONLY;
  218.     mp++;
  219.   }
  220.       
  221.   int f=open(filename,flags,S_IRWXU | S_IRWXG | S_IRWXO);
  222.   
  223.   if (f<0) 
  224.   {
  225.     fprintf(stderr,"(not found)\n");
  226.     f=-1;  // make sure this is -1
  227.   }
  228.  
  229.   long ret=lltl(f);
  230.   if (write(fd,&ret,sizeof(ret))!=sizeof(ret)) { close(fd); return ; }
  231.  
  232.   if (f<0)    // no file, sorry
  233.     close(fd);
  234.   else
  235.   {
  236.     long cur_pos=lseek(f,0,SEEK_CUR);
  237.     long size=lseek(f,0,SEEK_END);
  238.     lseek(f,cur_pos,SEEK_SET);
  239.     size=lltl(size);
  240.     if (write(fd,&size,sizeof(size))!=sizeof(size)) {  close(f); close(fd); return ; }
  241.  
  242.     first_nfs_client=new nfs_client(fd,f,first_nfs_client);
  243.     first_nfs_client->size=size;
  244.   }
  245. }
  246.  
  247. void remote_file::r_close(char *reason) 
  248.   if (reason)
  249.     fprintf(stderr,"remote_file : %s\n",reason);
  250.   if (socket_fd>=0) 
  251.   {
  252.     uchar cmd=NFCMD_CLOSE;
  253.     write(socket_fd,&cmd,1);
  254.     close(socket_fd); 
  255.   }
  256.   socket_fd=-1; 
  257. }
  258.  
  259. remote_file::remote_file(char *filename, char *mode, remote_file *Next)
  260. {
  261.   next=Next;
  262.   open_local=0;
  263.  
  264.   socket_fd=connect_to_server(filename);
  265.   if (socket_fd==-1)
  266.   { 
  267.     fprintf(stderr,"unable to connect\n");
  268.     return ;
  269.   }
  270.  
  271.   uchar sizes[3]={CLIENT_NFS,strlen(filename)+1,strlen(mode)+1};
  272.   if (write(socket_fd,sizes,3)!=3) { r_close("could not send open info"); return ; }
  273.   if (write(socket_fd,filename,sizes[1])!=sizes[1]) { r_close("could not send filename"); return ; }
  274.   if (write(socket_fd,mode,sizes[2])!=sizes[2]) { r_close("could not send mode"); return ; }
  275.  
  276.   long remote_file_fd;
  277.   if (read(socket_fd,&remote_file_fd,sizeof(remote_file_fd))!=sizeof(remote_file_fd)) 
  278.   { r_close("could not read remote fd"); return ; }   
  279.   remote_file_fd=lltl(remote_file_fd);
  280.   if (remote_file_fd<0) { r_close("remote fd is bad"); return ; }
  281.  
  282.   if (read(socket_fd,&size,sizeof(size))!=sizeof(size)) { r_close("could not read remote filesize"); return ; } 
  283. //  ulong remote_crc;
  284. //  if (read(socket_fd,&remote_crc,sizeof(remote_crc))!=sizeof(remote_crc)) { r_close("could not read remote checksum"); return ; }
  285. //  ulong local_crc=
  286.  
  287.   size=lltl(size);
  288. }
  289.  
  290. int remote_file::unbuffered_read(int out_fd, size_t count)
  291. {
  292.   if (socket_fd>=0 && count)
  293.   {
  294.     uchar cmd=NFCMD_READ;
  295.     if (write(socket_fd,&cmd,sizeof(cmd))!=sizeof(cmd)) { r_close("read : could not send command"); return 0; }
  296.  
  297.     long rsize=lltl(count);
  298.     if (write(socket_fd,&rsize,sizeof(rsize))!=sizeof(rsize)) { r_close("read : could not send size"); return 0; }
  299.  
  300.     long total_read=0,total;
  301.     char buf[READ_PACKET_SIZE];
  302.     ushort size;
  303.  
  304.     ushort packet_size;    
  305.     do
  306.     {
  307.       if (read(socket_fd,&packet_size,sizeof(packet_size))!=sizeof(packet_size)) 
  308.       {
  309.     fprintf(stderr,"could not read packet size\n");
  310.     return 0;
  311.       }
  312.       packet_size=lstl(packet_size);
  313.  
  314.       ushort size_read=read(socket_fd,buf+2,packet_size);   
  315.  
  316.       if (size_read!=packet_size) 
  317.       { 
  318.     if (read(socket_fd,buf+2+size_read,packet_size-size_read)!=packet_size-size_read)
  319.     {
  320.       fprintf(stderr,"incomplete packet\n"); 
  321.       return 0; 
  322.     }
  323.       }
  324.  
  325.       *((short *)buf)=packet_size;
  326.       if (write(out_fd,buf,packet_size+2)!=packet_size+2) comm_failed();
  327.  
  328.       total_read+=packet_size;
  329.       count-=packet_size;
  330.     } while (packet_size==READ_PACKET_SIZE-2 && count);     
  331.     return total_read;
  332.   }
  333.   return 0;
  334. }
  335.  
  336. int remote_file::unbuffered_tell()   // ask server where the offset of the file pointer is
  337. {
  338.   if (socket_fd>=0)
  339.   {
  340.     uchar cmd=NFCMD_TELL;
  341.     if (write(socket_fd,&cmd,sizeof(cmd))!=sizeof(cmd)) { r_close("tell : could not send command"); return 0; }
  342.  
  343.     long offset;
  344.     if (read(socket_fd,&offset,sizeof(offset))!=sizeof(offset)) { r_close("tell : could not read offset"); return 0; }    
  345.     return lltl(offset);
  346.   }    
  347.   return 0;
  348. }
  349.  
  350. int remote_file::unbuffered_seek(long offset)  // tell server to seek to a spot in a file
  351. {
  352.   if (socket_fd>=0)
  353.   {
  354.     uchar cmd=NFCMD_SEEK;
  355.     if (write(socket_fd,&cmd,sizeof(cmd))!=sizeof(cmd)) { r_close("seek : could not send command"); return 0; }
  356.  
  357.     long off=lltl(offset);
  358.     if (write(socket_fd,&off,sizeof(off))!=sizeof(off)) { r_close("seek : could not send offset"); return 0; }
  359.  
  360.     if (read(socket_fd,&offset,sizeof(offset))!=sizeof(offset)) { r_close("seek : could not read offset"); return 0; }    
  361.     return lltl(offset);
  362.   }    
  363.   return 0;
  364. }
  365.  
  366. int open_file(char *&filename, char *mode)
  367. {
  368.   if (filename[0]!='/' && filename[1]!='/' && default_fs_name[0])   // default file server?
  369.   {
  370.     char tmp_fn[500];  
  371.     sprintf(tmp_fn,"//%s/%s",default_fs_name,filename);
  372.     strcpy(filename,tmp_fn);
  373.   }
  374.  
  375.   if (filename[0]=='/' && filename[1]=='/')   // passive server file reference?
  376.   {
  377.     filename+=2;
  378.     remote_file *rf=new remote_file(filename,mode,remote_file_list);
  379.     if (rf->open_failure())
  380.     {
  381.       delete rf;
  382.       return -1;
  383.     }
  384.     else 
  385.     {
  386.       remote_file_list=rf;
  387.       return rf->socket_fd;
  388.     }      
  389.   }
  390.  
  391.   secure_filename(filename,mode);
  392.   if (filename[0]==0) return -1;
  393.  
  394.   int flags=0;
  395.   while (*mode)
  396.   {
  397.     if (*mode=='w') flags|=O_CREAT|O_RDWR;
  398.     else if (*mode=='r') flags|=O_RDONLY;
  399.     mode++;
  400.   }
  401.  
  402.   int f=open(filename,flags,S_IRWXU | S_IRWXG | S_IRWXO);
  403.   if (f>=0)
  404.   { close(f);
  405.     return -2;
  406.   }
  407.   
  408.   return -1;
  409. }
  410.  
  411. remote_file *find_rfile(int fd)
  412. {
  413.   remote_file *r=remote_file_list;
  414.   for (;r && r->socket_fd!=fd;r=r->next)
  415.   {
  416.     if (r->socket_fd==-1)
  417.     {
  418.       fprintf(stderr,"bad sock\n");
  419.     }
  420.   }
  421.   return r;
  422. }
  423.  
  424. void unlink_remote_file(remote_file *rf)
  425. {
  426.   if (rf==remote_file_list)
  427.     remote_file_list=rf->next;
  428.   else
  429.   {
  430.     remote_file *last=remote_file_list;
  431.     while (last->next && last->next!=rf) last=last->next;
  432.     last->next=rf->next;
  433.   }
  434. }
  435.  
  436. remote_file::~remote_file()
  437. { r_close(NULL); }
  438.  
  439.  
  440. int fetch_crcs(char *server)
  441. {
  442.   int socket_fd=connect_to_server(server);
  443.   if (socket_fd==-1)
  444.   { 
  445.     fprintf(stderr,"unable to connect\n");
  446.     return 0;
  447.   }
  448.  
  449.   uchar cmd=CLIENT_CRC_WAITER;
  450.   if (write(socket_fd,&cmd,1)!=1)  { close(socket_fd); return 0; }
  451.   if (read(socket_fd,&cmd,1)!=1)  { close(socket_fd); return 0; }
  452.   close(socket_fd);
  453.   return cmd;
  454.   
  455. }
  456.  
  457.  
  458.